package com.iot08.api.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.utils.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iot08.api.config.redis.RedisFilterService;
import com.iot08.api.constant.Constant;
import com.iot08.api.response.UserGoldCoinResp;
import com.iot08.api.vo.request.CreateGoldCoinPaymentReqBodyFormVO;
import com.iot08.api.vo.request.base.BaseAccountReqVO;
import com.iot08.common.entity.app.GoldCoinProductInfo;
import com.iot08.common.entity.app.UserGoldCoin;
import com.iot08.common.entity.app.VipMember;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Date;


/**
 * @author cwj
 * @description
 * @date 2025/3/6 14:07
 **/
@Slf4j
@Service
public class UserGoldCoinService extends BaseService<UserGoldCoin> {

    @Resource
    private RedisFilterService redisFilterService;

    /**
     * @description 查询用户的金币信息
     * @author cwj
     * @param [openId]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/7 15:12
     **/
    public ResponseMap queryUserGoldCoin(String openId) {
        Query query = new Query(Criteria.where("openid").is(openId).and("isEffect").is(1)).limit(1);
        UserGoldCoinResp userGoldCoinResp = mongoTemplate.findOne(query,UserGoldCoinResp.class,"user_gold_coin");
        ResponseMap res = ResponseMap.success();
        if(ObjectUtils.isEmpty(userGoldCoinResp)) {
            userGoldCoinResp = new UserGoldCoinResp();
            userGoldCoinResp.setCurrentGoldCoinNum(0);
            userGoldCoinResp.setGoldCoinTotal(0);
        }
        res.put("userGoldCoinResp",userGoldCoinResp);
        return res;
    }

    /**
     * @description 创建或更新用户购买的金币信息
     * @author cwj
     * @param [vo, goldCoin, orderId]
     * @return void
     * @date @time 2025/3/6 14:15
     **/
    public void createOrUpdateUserGoldCoin(CreateGoldCoinPaymentReqBodyFormVO vo, GoldCoinProductInfo goldCoin,String orderId){
        Query query = new Query(Criteria.where("openid").is(vo.getOpenid())).limit(1);
        UserGoldCoin userGoldCoin = this.findOne(query);
        if(ObjectUtils.isEmpty(userGoldCoin)){
            userGoldCoin = new UserGoldCoin();
            userGoldCoin.setOpenid(vo.getOpenid());
            userGoldCoin.setOrderid(orderId);
            userGoldCoin.setGoldCoinTotal(goldCoin.getGoldCoinNum());
            userGoldCoin.setCurrentGoldCoinNum(goldCoin.getGoldCoinNum());
            userGoldCoin.setGid(goldCoin.getId());
            userGoldCoin.setIsEffect(0);
            userGoldCoin.setType(goldCoin.getType());
            userGoldCoin.setCreateTime(new Date());
            userGoldCoin.setUpdateTime(new Date());
            this.save(userGoldCoin);
        } else {
            //会员存在，则先暂存会员更新的信息，等支付成功了，再进行会员信息更新
            JSONObject vm = new JSONObject();
            vm.put("orderid",orderId);
            vm.put("type",goldCoin.getType());
            vm.put("openid",vo.getOpenid());
            vm.put("gid",goldCoin.getId());
            vm.put("currentGoldCoinNum",goldCoin.getGoldCoinNum());
            redisFilterService.setex(orderId + Constant.REDIS_VIP_GOLD_COIN_POSTFIX,3*60*60,vm.toJSONString());
        }
    }


    /**
     * @description 更新用户金币信息
     * @author cwj
     * @param [orderId, isEffect]
     * @return void
     * @date @time 2025/3/6 16:06
     **/
    public void updateUserGoldCoin(String orderId, Integer isEffect)   {
        Update update = new Update();
        update.set("isEffect",isEffect);
        update.set("updateTime",new Date());
        //查询缓存信息
        String cacheData = redisFilterService.get(orderId + Constant.REDIS_VIP_GOLD_COIN_POSTFIX);
        log.info("更新用户金币信息......");
        if(!StringUtils.isEmpty(cacheData)){
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                //取出缓存的数据
                JSONObject dataCache = objectMapper.readValue(cacheData, JSONObject.class);
                Integer type = dataCache.getInteger("type");
                String openId = dataCache.getString("openid");
                String gId = dataCache.getString("gid");
                Integer currentGoldCoinNum = dataCache.getInteger("currentGoldCoinNum");
                //根据用户id查询用户金币信息
                UserGoldCoin userGoldCoin = queryUserGoldCoinByOpenId(openId);
                if (ObjectUtils.isNotEmpty(userGoldCoin)) {
                    String oldOrderid = userGoldCoin.getOrderid();
                    update.set("orderid",orderId);
                    update.set("gid",gId);
                    update.set("type",type);
                    update.set("currentGoldCoinNum",currentGoldCoinNum);
                    update.set("goldCoinTotal",ObjectUtils.isNotEmpty(userGoldCoin.getGoldCoinTotal())?userGoldCoin.getGoldCoinTotal()+currentGoldCoinNum:currentGoldCoinNum);
                    //更新会员信息
                    this.updateById(new ObjectId(userGoldCoin.getId()),update);
                    //清除之前可能存在的缓存信息，当下缓存等到下一个会员日充值时再清除,避免缓存过多
                    if(!StringUtils.isEmpty(redisFilterService.get(oldOrderid + Constant.REDIS_VIP_GOLD_COIN_POSTFIX))){
                        redisFilterService.del(oldOrderid + Constant.REDIS_VIP_GOLD_COIN_POSTFIX);
                    }
                } else {
                    userGoldCoin =  new UserGoldCoin();
                    //直接创建用户金币信息
                    userGoldCoin = userGoldCoin.bulidUserGoldCoin(userGoldCoin ,orderId, gId, type, openId, currentGoldCoinNum,isEffect);
                    this.save(userGoldCoin);
                }
                //支付成功了，清除当下下单时的缓存
                redisFilterService.del(orderId + Constant.REDIS_VIP_GOLD_COIN_POSTFIX);
            } catch (JsonProcessingException e){
                 log.error("更新用户金币信息时出现异常，异常信息为：{}",e.getMessage());
            }
        } else {
            //更新会员信息
            Query query = new Query(Criteria.where("orderid").is(orderId));
            this.update(query,update);
        }
    }

    /**
     * @description 根据用户id查询用户金币信息
     * @author cwj
     * @param [openId]
     * @return com.iot08.common.entity.app.UserGoldCoin
     * @date @time 2025/3/6 17:27
     **/
    public UserGoldCoin queryUserGoldCoinByOpenId(String openId) {
        Query query = new Query(Criteria.where("openid").is(openId)).limit(1);
        return this.findOne(query);
    }

    /**
     * @description 退款更新用户金币信息
     * @author cwj
     * @param [userGoldCoin, productType, isDeleteCurrentOrder, secondCurrentGoldCoinNum, secondOrderId, secondProductType]
     * @return void
     * @date @time 2025/3/6 18:14
     **/
    public void updateUserGoldCoinNum(UserGoldCoin userGoldCoin,Integer goldCoinNum, boolean isDeleteCurrentOrder,Integer secondCurrentGoldCoinNum,String secondOrderId,Integer secondProductType){
        if(!ObjectUtils.isEmpty(userGoldCoin)) {
            Update update = new Update();
            if(ObjectUtils.isEmpty(userGoldCoin.getGoldCoinTotal()) || (userGoldCoin.getGoldCoinTotal()-goldCoinNum) < 0){
                update.set("goldCoinTotal",0);
            } else {
                update.set("goldCoinTotal",userGoldCoin.getGoldCoinTotal()-goldCoinNum);
            }
            //删除当前订单且前面仍有有效支付的会员订单，且订单在有效期内
            if(isDeleteCurrentOrder) {
                if(ObjectUtils.isNotEmpty(secondCurrentGoldCoinNum)){
                    update.set("currentGoldCoinNum",secondCurrentGoldCoinNum);
                }
                if (!StringUtils.isEmpty(secondOrderId)){
                    update.set("orderid",secondOrderId);
                }
                if(!ObjectUtils.isEmpty(secondProductType)){
                    update.set("type",secondProductType);
                }
            }
            update.set("updateTime",new Date());
            this.updateById(new ObjectId(userGoldCoin.getId()),update);
        }
    }
    
    /**
     * @description 查询用户有效的金币信息
     * @author cwj
     * @param [openId]
     * @return com.iot08.common.entity.app.UserGoldCoin
     * @date @time 2025/3/13 15:56
     **/
    public UserGoldCoin queryEffectUserGoldCoinByOpenId(String openId){
        Query query = new Query(Criteria.where("openid").is(openId).and("isEffect").is(1)).limit(1);
        return this.findOne(query);
    }

    /**
     * @description 更新用户购买的金币数量，去掉被花掉的金币
     * @author cwj
     * @param [uid, costGoldCoinNum]
     * @return void
     * @date @time 2025/3/13 17:34
     **/
    public void updateUserGoldCoinNumById(String uid,Integer costGoldCoinNum){
        Update update = new Update().inc("goldCoinTotal", -costGoldCoinNum);
        this.updateById(new ObjectId(uid),update);
    }
}
